﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Campus {
    public static class BuildRequirements {
        public class Requirements {
            private List<Type> m_buildings;
            static public Type GetType(Buildings building) {
                Type buildingType;
                switch (building) {
                    case Buildings.CollegeOfEngineering:
                        buildingType = Type.GetType("Campus.CollegeOfEngineering");
                        break;
                    case Buildings.CleanRoom:
                        buildingType = Type.GetType("Campus.CleanRoom");
                        break;
                    case Buildings.Scholarship:
                        buildingType = Type.GetType("Campus.Scholarship");
                        break;
                    case Buildings.ExperimentalLaboratory:
                        buildingType = Type.GetType("Campus.ExperimentalLaboratory");
                        break;
                    case Buildings.SchoolCafeteria:
                        buildingType = Type.GetType("Campus.SchoolCafeteria");
                        break;
                    case Buildings.MothersBasement:
                        buildingType = Type.GetType("Campus.MothersBasement");
                        break;
                    case Buildings.InterdimensionalPortal:
                        buildingType = Type.GetType("Campus.InterdimensionalPortal");
                        break;
                    case Buildings.Dispatch:
                        buildingType = Type.GetType("Campus.Dispatch");
                        break;
                    case Buildings.CollegeOfArchitecture:
                        buildingType = Type.GetType("Campus.CollegeOfArchitecture");
                        break;
                    case Buildings.CoffeeShop:
                        buildingType = Type.GetType("Campus.CoffeeShop");
                        break;
                    case Buildings.GatewayToHell:
                        buildingType = Type.GetType("Campus.GatewayToHell");
                        break;
                    case Buildings.DownByTheRiver:
                        buildingType = Type.GetType("Campus.DownByTheRiver");
                        break;
                    default:
                        //should never get here
                        buildingType = null;
                        break;
                }
                return buildingType;
            }

            static public Type GetType(Units building) {
                Type unitType;
                switch (building) {
                    case Units.Architect:
                        unitType = Type.GetType("Campus.Architect");
                        break;
                    case Units.Biologist:
                        unitType = Type.GetType("Campus.Biologist");
                        break;
                    case Units.CampusShuttle:
                        unitType = Type.GetType("Campus.CampusShuttle");
                        break;
                    case Units.ComputerScientist:
                        unitType = Type.GetType("Campus.ComputerScientist");
                        break;
                    case Units.MechanicalEngineer:
                        unitType = Type.GetType("Campus.MechanicalEngineer");
                        break;
                    case Units.Physicist:
                        unitType = Type.GetType("Campus.Physicist");
                        break;
                    case Units.Robot:
                        unitType = Type.GetType("Campus.Robot");
                        break;
                    default:
                        //should never get here
                        unitType = null;
                        break;
                }
                return unitType;
            }

            public void AddBuilding(Buildings building) {
                m_buildings.Add(GetType(building));
            }

            private int m_researchCost;
            public int ResearchCost {
                get { return m_researchCost; }
            }

            private int m_moneyCost;
            public int MoneyCost {
                get { return m_moneyCost; }
            }

            private int m_foodCost;
            public int FoodCost {
                get { return m_foodCost; }
            }

            private int m_buildTime;
            public int BuildTime {
                get { return m_buildTime; }
            }

            public Requirements(int researchCost, int moneyCost, int foodCost, int buildTime) {
                m_researchCost = researchCost;
                m_moneyCost = moneyCost;
                m_foodCost = foodCost;
                m_buildTime = buildTime;
                m_buildings = new List<Type>();
            }

            public Requirements(int researchCost, int moneyCost, int foodCost, int buildTime, Buildings[] buildings) {
                m_researchCost = researchCost;
                m_moneyCost = moneyCost;
                m_foodCost = foodCost;
                m_buildTime = buildTime;
                m_buildings = new List<Type>();
                foreach(Buildings b in buildings) {
                    AddBuilding(b);
                }
            }

            public bool CheckRequirements(Player player) {

                if (player.Research < m_researchCost) {
                    return false;
                }
                if (player.Money < m_moneyCost) {
                    return false;
                }
                if (player.MaxFood - player.UsedFood < m_foodCost) {
                    return false;
                }
                foreach (Type rb in m_buildings) {
                    bool hasBuilding = false;
                    foreach (Structure s in player.Structures) {
                        if (s.GetType() == rb) {
                            hasBuilding = true;
                            break;
                        }
                    }

                    if (!hasBuilding) {
                        return false;
                    }
                }

                return true;
            }
        }

        //UNITS
        //---Science Units
        static private Requirements m_physicistReqs = new Requirements(0, 100, 1, 2000);
        static private Requirements m_mechanicalEngineerReqs = new Requirements(0, 50, 1, 2000);
        static private Requirements m_biologistReqs = new Requirements(50, 100, 2, 4000);
        static private Requirements m_computerScientistReqs = new Requirements(100, 200, 2, 4000);
        static private Requirements m_deLoreanReqs = new Requirements(200, 100, 2, 1000);
        static private Requirements m_robotReqs = new Requirements(150, 100, 2, 1000);
        static private Requirements m_campusShuttleReqs = new Requirements(200, 100, 2, 1000);
        //---Humanities Units
        static private Requirements m_architectReqs = new Requirements(0, 50, 1, 2000);

        //STRUCTURES
        //---Science Structures
        static private Requirements m_collegeOfEngineeringReqs = new Requirements(0, 100, 0, 4000);
        static private Requirements m_cleanRoomReqs = new Requirements(100, 100, 0, 4000, new Buildings[] {Buildings.CollegeOfEngineering});
        static private Requirements m_scholarshipReqs = new Requirements(0, 50, 0, 3000, new Buildings[] {Buildings.CollegeOfEngineering});
        static private Requirements m_experimentalLaboratoryReqs = new Requirements(0, 50, 0, 3000, new Buildings[] {Buildings.CollegeOfEngineering});
        static private Requirements m_schoolCafeteriaReqs = new Requirements(0, 50, 0, 2000, new Buildings[] {Buildings.CollegeOfEngineering});
        static private Requirements m_mothersBasementReqs = new Requirements(500, 500, 0, 10000, new Buildings[] { Buildings.CollegeOfEngineering });
        static private Requirements m_interdimensionalPortalReqs = new Requirements(200, 200, 0, 5000, new Buildings[] { Buildings.CollegeOfEngineering, Buildings.ExperimentalLaboratory });
        static private Requirements m_dispatchReqs = new Requirements(0, 400, 0, 3500, new Buildings[] { Buildings.CollegeOfEngineering, Buildings.Scholarship });
        //---Humanities Structures
        static private Requirements m_collegeOfArchitectureReqs = new Requirements(0, 100, 0, 4000);
        static private Requirements m_coffeeShopReqs = new Requirements(0, 50, 0, 2000, new Buildings[] {Buildings.CollegeOfEngineering});
        static private Requirements m_gatewayToHellReqs = new Requirements(500, 500, 0, 4000, new Buildings[] { Buildings.CollegeOfEngineering });
        static private Requirements m_downByTheRiverReqs = new Requirements(500, 500, 0, 4000, new Buildings[] { Buildings.CollegeOfEngineering });
        
        public enum Units {
            //Sciences
            Physicist,
            MechanicalEngineer,
            Biologist,
            ComputerScientist,
            DeLorean,
            Robot,
            CampusShuttle,
            //Humanities
            Architect
        }
        public enum Buildings {
            //Sciences
            CollegeOfEngineering,
            CleanRoom,
            Scholarship,
            ExperimentalLaboratory,
            SchoolCafeteria,
            MothersBasement,
            InterdimensionalPortal,
            Dispatch,
            //Humanities
            CollegeOfArchitecture,
            CoffeeShop,
            GatewayToHell,
            DownByTheRiver
        }
        static public Requirements GetRequirements(Buildings buildingType) {
            switch (buildingType) {
                case Buildings.CollegeOfEngineering:
                    return m_collegeOfEngineeringReqs;
                case Buildings.CleanRoom:
                    return m_cleanRoomReqs;
                case Buildings.ExperimentalLaboratory:
                    return m_experimentalLaboratoryReqs;
                case Buildings.Scholarship:
                    return m_scholarshipReqs;
                case Buildings.SchoolCafeteria:
                    return m_schoolCafeteriaReqs;
                case Buildings.MothersBasement:
                    return m_mothersBasementReqs;
                case Buildings.InterdimensionalPortal:
                    return m_interdimensionalPortalReqs;
                case Buildings.Dispatch:
                    return m_dispatchReqs;
                case Buildings.CollegeOfArchitecture:
                    return m_collegeOfArchitectureReqs;
                case Buildings.CoffeeShop:
                    return m_coffeeShopReqs;
                case Buildings.GatewayToHell:
                    return m_gatewayToHellReqs;
                case Buildings.DownByTheRiver:
                    return m_downByTheRiverReqs;
                default:
                    //should never get here
                    return null;
            }
        }
        static public Requirements GetRequirements(Units unitType) {
            switch (unitType) {
                case Units.Physicist:
                    return m_physicistReqs;
                case Units.MechanicalEngineer:
                    return m_mechanicalEngineerReqs;
                case Units.Biologist:
                    return m_biologistReqs;
                case Units.ComputerScientist:
                    return m_computerScientistReqs;
                case Units.DeLorean:
                    return m_deLoreanReqs;
                case Units.Robot:
                    return m_robotReqs;
                case Units.CampusShuttle:
                    return m_campusShuttleReqs;
                case Units.Architect:
                    return m_architectReqs;
                default:
                    //shoulc never get here
                    return null;
            }
        }

        static public Unit BuildUnit(Units type, Player owner) {
            switch (type) {
                case Units.Physicist:
                    return new Physicist(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.MechanicalEngineer:
                    return new MechanicalEngineer(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.Biologist:
                    return new Biologist(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.ComputerScientist:
                    return new ComputerScientist(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.DeLorean:
                    return new Physicist(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.Robot:
                    return new Robot(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.CampusShuttle:
                    return new CampusShuttle(new Vector2(0, 0), owner, owner.CurrentLevel);
                case Units.Architect:
                    return new Architect(new Vector2(0, 0), owner, owner.CurrentLevel);
                default:
                    //shoulc never get here
                    return null;
            }
        }

        static public Structure BuildStructure(Buildings type, Player owner) {
            switch (type) {
                case Buildings.CollegeOfEngineering:
                    return new CollegeOfEngineering(owner, owner.CurrentLevel);
                case Buildings.CleanRoom:
                    return new CleanRoom(owner, owner.CurrentLevel);
                case Buildings.ExperimentalLaboratory:
                    return new ExperimentalLaboratory(owner, owner.CurrentLevel);
                case Buildings.Scholarship:
                    return new Scholarship(owner, owner.CurrentLevel);
                case Buildings.SchoolCafeteria:
                    return new SchoolCafeteria(owner, owner.CurrentLevel);
                case Buildings.MothersBasement:
                    return new MothersBasement(owner, owner.CurrentLevel);
                case Buildings.InterdimensionalPortal:
                    return new InterdimensionalPortal(owner, owner.CurrentLevel);
                case Buildings.Dispatch:
                    return new Dispatch(owner, owner.CurrentLevel);
                case Buildings.CollegeOfArchitecture:
                    return new CollegeOfArchitecture(owner, owner.CurrentLevel);
                case Buildings.CoffeeShop:
                    return new CoffeeShop(owner, owner.CurrentLevel);
                case Buildings.GatewayToHell:
                    return new GatewayToHell(owner, owner.CurrentLevel);
                case Buildings.DownByTheRiver:
                    return new DownByTheRiver(owner, owner.CurrentLevel);
                default:
                    //should never get here
                    return null;
            }
        }

        static public Texture2D GetStructureBuildingTexture(Buildings type) {
            switch (type) {
                case Buildings.CleanRoom:
                    return CleanRoom.BuildingTexture;
                case Buildings.Dispatch:
                    return Dispatch.BuildingTexture;
                case Buildings.ExperimentalLaboratory:
                    return ExperimentalLaboratory.BuildingTexture;
                case Buildings.InterdimensionalPortal:
                    return InterdimensionalPortal.BuildingTexture;
                case Buildings.MothersBasement:
                    return MothersBasement.BuildingTexture;
                case Buildings.CollegeOfEngineering:
                    return CollegeOfEngineering.BuildingTexture;
                case Buildings.Scholarship:
                    return Scholarship.BuildingTexture;
                case Buildings.SchoolCafeteria:
                    return SchoolCafeteria.BuildingTexture;
                case Buildings.CollegeOfArchitecture:
                    return CollegeOfArchitecture.BuildingTexture;
                case Buildings.CoffeeShop:
                    return CoffeeShop.BuildingTexture;
                case Buildings.GatewayToHell:
                    return GatewayToHell.BuildingTexture;
                case Buildings.DownByTheRiver:
                    return DownByTheRiver.BuildingTexture;
                default:
                    return CollegeOfEngineering.BuildingTexture;
            }
        }

        static public Texture2D GetStructureConstructionTexture(Buildings type) {
            switch (type) {
                case Buildings.CleanRoom:
                    return CleanRoom.ConstructionTexture;
                case Buildings.Dispatch:
                    return Dispatch.ConstructionTexture;
                case Buildings.ExperimentalLaboratory:
                    return ExperimentalLaboratory.ConstructionTexture;
                case Buildings.InterdimensionalPortal:
                    return InterdimensionalPortal.ConstructionTexture;
                case Buildings.MothersBasement:
                    return MothersBasement.ConstructionTexture;
                case Buildings.CollegeOfEngineering:
                    return CollegeOfEngineering.ConstructionTexture;
                case Buildings.Scholarship:
                    return Scholarship.ConstructionTexture;
                case Buildings.SchoolCafeteria:
                    return SchoolCafeteria.ConstructionTexture;
                case Buildings.CollegeOfArchitecture:
                    return CollegeOfArchitecture.ConstructionTexture;
                case Buildings.CoffeeShop:
                    return CoffeeShop.ConstructionTexture;
                case Buildings.GatewayToHell:
                    return GatewayToHell.ConstructionTexture;
                case Buildings.DownByTheRiver:
                    return DownByTheRiver.ConstructionTexture;
                default:
                    return CollegeOfEngineering.ConstructionTexture;
            }
        }

        static public Texture2D GetStructureTeamColorTexture(Buildings type) {
            switch (type) {
                case Buildings.CleanRoom:
                    return CleanRoom.StaticTeamColorTexture;
                case Buildings.Dispatch:
                    return Dispatch.StaticTeamColorTexture;
                case Buildings.ExperimentalLaboratory:
                    return ExperimentalLaboratory.StaticTeamColorTexture;
                case Buildings.InterdimensionalPortal:
                    return InterdimensionalPortal.StaticTeamColorTexture;
                case Buildings.MothersBasement:
                    return MothersBasement.StaticTeamColorTexture;
                case Buildings.CollegeOfEngineering:
                    return CollegeOfEngineering.StaticTeamColorTexture;
                case Buildings.Scholarship:
                    return Scholarship.StaticTeamColorTexture;
                case Buildings.SchoolCafeteria:
                    return SchoolCafeteria.StaticTeamColorTexture;
                case Buildings.CollegeOfArchitecture:
                    return CollegeOfArchitecture.StaticTeamColorTexture;
                case Buildings.CoffeeShop:
                    return CoffeeShop.StaticTeamColorTexture;
                case Buildings.GatewayToHell:
                    return GatewayToHell.StaticTeamColorTexture;
                case Buildings.DownByTheRiver:
                    return DownByTheRiver.StaticTeamColorTexture;
                default:
                    return CollegeOfEngineering.StaticTeamColorTexture;
            }
        }
        static public Vector2 GetStructureOrigin(Buildings type) {
            switch (type) {
                case BuildRequirements.Buildings.CleanRoom:
                    return CleanRoom.StaticOrigin;
                case BuildRequirements.Buildings.Dispatch:
                    return Dispatch.StaticOrigin;
                case BuildRequirements.Buildings.ExperimentalLaboratory:
                    return ExperimentalLaboratory.StaticOrigin;
                case BuildRequirements.Buildings.InterdimensionalPortal:
                    return InterdimensionalPortal.StaticOrigin;
                case BuildRequirements.Buildings.MothersBasement:
                    return MothersBasement.StaticOrigin;
                case BuildRequirements.Buildings.CollegeOfEngineering:
                    return CollegeOfEngineering.StaticOrigin;
                case BuildRequirements.Buildings.Scholarship:
                    return Scholarship.StaticOrigin;
                case BuildRequirements.Buildings.SchoolCafeteria:
                    return SchoolCafeteria.StaticOrigin;
                case Buildings.CollegeOfArchitecture:
                    return CollegeOfArchitecture.StaticOrigin;
                case Buildings.CoffeeShop:
                    return CoffeeShop.StaticOrigin;
                case Buildings.GatewayToHell:
                    return GatewayToHell.StaticOrigin;
                case Buildings.DownByTheRiver:
                    return DownByTheRiver.StaticOrigin;
                default:
                    return CollegeOfEngineering.StaticOrigin;
            }
        }

        static public List<Vector2> GetStructureTilesOccupied(Buildings type) {
            switch (type) {
                case BuildRequirements.Buildings.CleanRoom:
                    return CleanRoom.StaticTilesOccupied;
                case BuildRequirements.Buildings.Dispatch:
                    return Dispatch.StaticTilesOccupied;
                case BuildRequirements.Buildings.ExperimentalLaboratory:
                    return ExperimentalLaboratory.StaticTilesOccupied;
                case BuildRequirements.Buildings.InterdimensionalPortal:
                    return InterdimensionalPortal.StaticTilesOccupied;
                case BuildRequirements.Buildings.MothersBasement:
                    return MothersBasement.StaticTilesOccupied;
                case BuildRequirements.Buildings.CollegeOfEngineering:
                    return CollegeOfEngineering.StaticTilesOccupied;
                case BuildRequirements.Buildings.Scholarship:
                    return Scholarship.StaticTilesOccupied;
                case BuildRequirements.Buildings.SchoolCafeteria:
                    return SchoolCafeteria.StaticTilesOccupied;
                case Buildings.CollegeOfArchitecture:
                    return CollegeOfArchitecture.StaticTilesOccupied;
                case Buildings.CoffeeShop:
                    return CoffeeShop.StaticTilesOccupied;
                case Buildings.GatewayToHell:
                    return GatewayToHell.StaticTilesOccupied;
                case Buildings.DownByTheRiver:
                    return DownByTheRiver.StaticTilesOccupied;
                default:
                    return CollegeOfEngineering.StaticTilesOccupied;
            }
        }
    }
}
